// For an ASCII version of the wrapper delete or comment the next line.
// By default a Unicode version will be build.
#define UNICODE


using System;
using System.Runtime.InteropServices;


namespace SproxDesFireAPI
{

  /************************************************************/
  /// <summary>
  /// Structure for returning the information supplied by the GetVersion command.
  /// </summary>
  [StructLayout(LayoutKind.Sequential)] public class DF_VERSION_INFO
  {
    public byte bHwVendorID;
    public byte bHwType;
    public byte bHwSubType;
    public byte bHwMajorVersion;
    public byte bHwMinorVersion;
    public byte bHwStorageSize;
    public byte bHwProtocol;
    public byte bSwVendorID;
    public byte bSwType;
    public byte bSwSubType;
    public byte bSwMajorVersion;
    public byte bSwMinorVersion;
    public byte bSwStorageSize;
    public byte bSwProtocol;
    public byte[] abUid;
    public byte[] abBatchNo;
    public byte bProductionCW;
    public byte bProductionYear;

    public DF_VERSION_INFO()
    {
      abUid = new byte[7];
      abBatchNo = new byte[5];
    }
  }

  /************************************************************/



  /************************************************************/
  /// <summary>
  /// Generic file settings class.
  /// </summary>
  [StructLayout(LayoutKind.Sequential)] public abstract class FILE_SETTINGS
  {
    public static readonly int MAX_FILE_SETTINGS_LENGTH = 13;
  }

  /// <summary>
  /// Standard Data Files and Backup Data Files.
  /// </summary>
  [StructLayout(LayoutKind.Sequential)]
    public class ST_DATA_FILE_SETTINGS:FILE_SETTINGS
  {
    public uint eFileSize;
  }

  /// <summary>
  /// Value Files.
  /// </summary>
  [StructLayout(LayoutKind.Sequential)]
    public class ST_VALUE_FILE_SETTINGS:FILE_SETTINGS
  {
    public int lLowerLimit;
    public int lUpperLimit;
    public uint eLimitedCredit;
    public byte bLimitedCreditEnabled;
  }

  /// <summary>
  /// Linear Record Files and Cyclic Record Files.
  /// </summary>
  [StructLayout(LayoutKind.Sequential)]
    public class ST_RECORD_FILE_SETTINGS:FILE_SETTINGS
  {
    public uint eRecordSize;
    public uint eMaxNRecords;
    public uint eCurrNRecords;
  }

  /*
   * FieldOffset attributes not available with the .NET compact Framework.
   * 
   * /
   [StructLayout(LayoutKind.Explicit)]
   public struct DF_ADDITIONAL_FILE_SETTINGS
   {
   [FieldOffset(0)] ST_DATA_FILE_SETTINGS   stDataFileSettings;
   [FieldOffset(0)] ST_VALUE_FILE_SETTINGS  stValueFileSettings;
   [FieldOffset(0)] ST_RECORD_FILE_SETTINGS stRecordFileSettings;
   }
   */

  /************************************************************/



  /************************************************************/
  public abstract class SproxDesFire
  {
#region Constantes

    /**Constantes*********************/
    public const int APPLICATION_ID_SIZE = 3;
    public const int MAX_INFO_FRAME_SIZE = 60;

    public const byte INVALIDATE_AUTHENTICATION = 0xFF;

    /*
     * DESFire commands (codes sent by the PCD)
     * ----------------
     */
    public const byte DF_AUTHENTICATE = 0x0A;
    public const byte DF_CREDIT = 0x0C;
    public const byte DF_LIMITED_CREDIT = 0x1C;
    public const byte DF_WRITE_RECORD = 0x3B;
    public const byte DF_WRITE_DATA = 0x3D;
    public const byte DF_GET_KEY_SETTINGS = 0x45;
    public const byte DF_CHANGE_KEY_SETTINGS = 0x54;
    public const byte DF_SELECT_APPLICATION = 0x5A;
    public const byte DF_CHANGE_FILE_SETTINGS = 0x5F;
    public const byte DF_GET_VERSION = 0x60;
    public const byte DF_GET_KEY_VERSION = 0x64;
    public const byte DF_GET_APPLICATION_IDS = 0x6A;
    public const byte DF_GET_VALUE = 0x6C;
    public const byte DF_GET_FILE_IDS = 0x6F;
    public const byte DF_ABORT_TRANSACTION = 0xA7;
    public const byte DF_READ_RECORDS = 0xBB;
    public const byte DF_READ_DATA = 0xBD;
    public const byte DF_CREATE_CYCLIC_RECORD_FILE = 0xC0;
    public const byte DF_CREATE_LINEAR_RECORD_FILE = 0xC1;
    public const byte DF_CHANGE_KEY = 0xC4;
    public const byte DF_COMMIT_TRANSACTION = 0xC7;
    public const byte DF_CREATE_APPLICATION = 0xCA;
    public const byte DF_CREATE_BACKUP_DATA_FILE = 0xCB;
    public const byte DF_CREATE_VALUE_FILE = 0xCC;
    public const byte DF_CREATE_STD_DATA_FILE = 0xCD;
    public const byte DF_DELETE_APPLICATION = 0xDA;
    public const byte DF_DEBIT = 0xDC;
    public const byte DF_DELETE_FILE = 0xDF;
    public const byte DF_CLEAR_RECORD_FILE = 0xEB;
    public const byte DF_GET_FILE_SETTINGS = 0xF5;
    public const byte DF_FORMAT_PICC = 0xFC;

    /*
     * DESFire status (codes returned by the PICC)
     * --------------
     */
    public const byte DF_OPERATION_OK = 0x00;
    public const byte DF_NO_CHANGES = 0x0C;
    public const byte DF_OUT_OF_EEPROM_ERROR = 0x0E;
    public const byte DF_ILLEGAL_COMMAND_CODE = 0x1C;
    public const byte DF_INTEGRITY_ERROR = 0x1E;
    public const byte DF_NO_SUCH_KEY = 0x40;
    public const byte DF_LENGTH_ERROR = 0x7E;
    public const byte DF_PERMISSION_DENIED = 0x9D;
    public const byte DF_PARAMETER_ERROR = 0x9E;
    public const byte DF_APPLICATION_NOT_FOUND = 0xA0;
    public const byte DF_APPL_INTEGRITY_ERROR = 0xA1;
    public const byte DF_AUTHENTICATION_CORRECT = 0xAC;
    public const byte DF_AUTHENTICATION_ERROR = 0xAE;
    public const byte DF_ADDITIONAL_FRAME = 0xAF;
    public const byte DF_BOUNDARY_ERROR = 0xBE;
    public const byte DF_CARD_INTEGRITY_ERROR = 0xC1;
    public const byte DF_COMMAND_ABORTED = 0xCA;
    public const byte DF_CARD_DISABLED_ERROR = 0xCD;
    public const byte DF_COUNT_ERROR = 0xCE;
    public const byte DF_DUPLICATE_ERROR = 0xDE;
    public const byte DF_FILE_NOT_FOUND = 0xF0;
    public const byte DF_FILE_INTEGRITY_ERROR = 0xF1;
    public const byte DF_EEPROM_ERROR = 0xEE;

    /*
     * DESFire API status/error codes.
     * -------
     */
    public const short DFCARD_ERROR = -1000;
    public const short DFCARD_LIB_CALL_ERROR = DFCARD_ERROR + 1;
    public const short DFCARD_OUT_OF_MEMORY = DFCARD_ERROR + 2;
    public const short DFCARD_OVERFLOW = DFCARD_ERROR + 3;
    public const short DFCARD_WRONG_KEY = DFCARD_ERROR + 4;
    public const short DFCARD_WRONG_MAC = DFCARD_ERROR + 5;
    public const short DFCARD_WRONG_CRC = DFCARD_ERROR + 6;
    public const short DFCARD_WRONG_LENGTH = DFCARD_ERROR + 7;
    public const short DFCARD_WRONG_PADDING = DFCARD_ERROR + 8;
    public const short DFCARD_WRONG_FILE_TYPE = DFCARD_ERROR + 9;
    public const short DFCARD_WRONG_RECORD_SIZE = DFCARD_ERROR + 10;

    /*
     * DESFire file types
     * ------------------
     */
    public const byte DF_STANDARD_DATA_FILE = 0x00;
    public const byte DF_BACKUP_DATA_FILE = 0x01;
    public const byte DF_VALUE_FILE = 0x02;
    public const byte DF_LINEAR_RECORD_FILE = 0x03;
    public const byte DF_CYCLIC_RECORD_FILE = 0x04;

    /*
     * DESFire communication mode flag combinations.
     * -------
     */
    public const byte DF_COMM_MODE_PLAIN = 0x00;
    public const byte DF_COMM_MODE_MACED = 0x01;
    public const byte DF_COMM_MODE_PLAIN2 = 0x02;
    public const byte DF_COMM_MODE_ENCIPHERED = 0x03;

    /*
     * DESFire access rights
     * ---------------------
     */
    /* Shift counts for extracting the individual AccessRight settings. */
    public const int DF_GET_READ_ONLY = 12;
    public const int DF_GET_WRITE_ONLY = 8;
    public const int DF_GET_READ_WRITE = 4;

    /* AccessRights masks. */
    public const ushort DF_READ_ONLY = 0xF000;
    public const ushort DF_WRITE_ONLY = 0x0F00;
    public const ushort DF_READ_WRITE = 0x00F0;
    public const ushort DF_CHANGE_ACCESS_RIGHTS = 0x000F;

    /*********************************/
#endregion

#region SelectCid
    /**SelectCid**************/
      [DllImport
       ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
        "DesFireCard_SelectCid")] public static extern short SelectCid(byte cid);
#endregion

#region Authenticate
    /**Authenticate*******************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_Authenticate")] public static extern short
Authenticate(byte bKeyNumber, byte[]pbAccessKey);

#endregion

#region Key
    /**ChangeKeySettings**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ChangeKeySettings")] public static extern short
ChangeKeySettings(byte key_settings);

    /**GetKeySettings*****************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetKeySettings")] public static extern short
GetKeySettings(ref byte key_settings, ref byte key_count);

    /**ChangeKey**********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ChangeKey")] public static extern short ChangeKey(byte
                                                                     key_number,
                                                                     byte
                                                                     []new_key,
                                                                     byte
                                                                     []old_key);

    /**GetKeyVersion******************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetKeyVersion")] public static extern short
GetKeyVersion(byte bKeyNumber, ref byte pbKeyVersion);

#endregion

#region FormatPICC
    /**FormatPICC*********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_FormatPICC")] public static extern short FormatPICC();

#endregion

#region Application
      /**CreateApplication**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CreateApplication")] public static extern short
CreateApplication(uint aid, byte key_settings, byte keys_count);

    /**DeleteApplication**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_DeleteApplication")] public static extern short
DeleteApplication(uint aid);

    /**GetApplicationIDs**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetApplicationIDs")] public static extern short
GetApplicationIDs(byte aid_max_count, uint[]aid_list, ref byte aid_count);

    /**SelectApplication**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_SelectApplication")] public static extern short
SelectApplication(uint aid);

#endregion

#region Get Version/FileIDs
    /**GetVersion*********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetVersion")] public static extern short
GetVersion(DF_VERSION_INFO pVersionInfo);

    /**GetFileIDs*********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetFileIDs")] public static extern short GetFileIDs(byte
                                                                       fid_max_count,
                                                                       byte
                                                                       []fid_list,
                                                                       ref
                                                                       byte
                                                                       fid_count);
#endregion

#region FileSettings

      /**GetFileSettings****************/
      [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetFileSettings")] public static extern short
GetFileSettings(byte file_id, ref byte file_type, ref byte comm_mode,
             ref ushort access_rights, byte[]additionnal_settings_array);

    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ExplainDataFileSettings")] public static extern short
ExplainDataFileSettings(byte[]additionnal_settings_array, ref uint eFileSize);

    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ExplainValueFileSettings")] public static extern short
ExplainValueFileSettings(byte[]additionnal_settings_array, ref int lLowerLimit,
                      ref int lUpperLimit, ref uint eLimitedCredit,
                      ref byte bLimitedCreditEnabled);

    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ExplainRecordFileSettings")] public static extern short
ExplainRecordFileSettings(byte[]additionnal_settings_array, ref uint eRecordSize,
                       ref uint eMaxNRecords, ref uint eCurrNRecords);

    public static short EasyGetFileSettings(byte file_id, ref byte file_type,
                                            ref byte comm_mode,
                                            ref ushort access_rights,
                                            out FILE_SETTINGS
                                            additionnal_settings)
    {
      short rc;
        byte[] buffer = new byte[FILE_SETTINGS.MAX_FILE_SETTINGS_LENGTH];

        additionnal_settings = null;

        rc =
        GetFileSettings(file_id, ref file_type, ref comm_mode,
                        ref access_rights, buffer);
      if (rc != DF_OPERATION_OK)
          return rc;

      switch (file_type)
      {
        case DF_STANDARD_DATA_FILE:
        case DF_BACKUP_DATA_FILE:
        {
          ST_DATA_FILE_SETTINGS tmp;
          uint eFileSize = 0;

            rc = ExplainDataFileSettings(buffer, ref eFileSize);
          if (rc != DF_OPERATION_OK)
              return rc;

            tmp = new ST_DATA_FILE_SETTINGS();
            tmp.eFileSize = eFileSize;

            additionnal_settings = tmp;

            return DF_OPERATION_OK;
        }

          case DF_VALUE_FILE:
        {
          ST_VALUE_FILE_SETTINGS tmp;
          int lLowerLimit = 0;
          int lUpperLimit = 0;
          uint eLimitedCredit = 0;
          byte bLimitedCreditEnabled = 0;

          rc =
            ExplainValueFileSettings(buffer, ref lLowerLimit,
                                     ref lUpperLimit,
                                     ref eLimitedCredit,
                                     ref bLimitedCreditEnabled);
          if (rc != DF_OPERATION_OK)
            return rc;

          tmp = new ST_VALUE_FILE_SETTINGS();
          tmp.lLowerLimit = lLowerLimit;
          tmp.lUpperLimit = lUpperLimit;
          tmp.eLimitedCredit = eLimitedCredit;
          tmp.bLimitedCreditEnabled = bLimitedCreditEnabled;

          additionnal_settings = tmp;

          return DF_OPERATION_OK;
        }

        case DF_LINEAR_RECORD_FILE:
        case DF_CYCLIC_RECORD_FILE:
        {
          ST_RECORD_FILE_SETTINGS tmp;
          uint eRecordSize = 0;
          uint eMaxNRecords = 0;
          uint eCurrNRecords = 0;

          rc =
            ExplainRecordFileSettings(buffer, ref eRecordSize,
                                      ref eMaxNRecords, ref eCurrNRecords);
          if (rc != DF_OPERATION_OK)
            return rc;

          tmp = new ST_RECORD_FILE_SETTINGS();
          tmp.eRecordSize = eRecordSize;
          tmp.eMaxNRecords = eMaxNRecords;
          tmp.eCurrNRecords = eCurrNRecords;

          additionnal_settings = tmp;

          return DF_OPERATION_OK;
        }
      }

      // Unknown file type
      return DFCARD_WRONG_FILE_TYPE;
  }

    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ChangeFileSettings")] public static extern short
ChangeFileSettings(byte file_id, byte comm_mode, ushort access_rights);

    /**CreateStdDataFile**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CreateStdDataFile")] public static extern short
CreateStdDataFile(byte file_id, byte comm_mode, ushort access_rights,
               uint file_size);
#endregion

#region Create/Delete File
    /**CreateBackupDataFile***********/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CreateBackupDataFile")] public static extern short
CreateBackupDataFile(byte file_id, byte comm_mode, ushort access_rights,
                  uint file_size);

    /**CreateValueFile****************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CreateValueFile")] public static extern short
CreateValueFile(byte file_id, byte comm_mode, ushort access_rights,
             int lower_limit, int upper_limit, int initial_value,
             byte limited_credit_enabled);

    /**CreateLinearRecordFile*********/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CreateLinearRecordFile")] public static extern short
CreateLinearRecordFile(byte file_id, byte comm_mode, ushort access_rights,
                    uint record_size, uint max_records);

    /**CreateCyclicRecordFile*********/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CreateCyclicRecordFile")] public static extern short
CreateCyclicRecordFile(byte file_id, byte comm_mode, ushort access_rights,
                    uint record_size, uint max_records);

    /**DeleteFile*********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_DeleteFile")] public static extern short DeleteFile(byte
                                                                       file_id);
#endregion

#region Read/Write/Get
    /**ReadData***********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ReadData")] public static extern short ReadData(byte
                                                                   file_id,
                                                                   byte
                                                                   comm_mode,
                                                                   uint
                                                                   from_offset,
                                                                   uint
                                                                   max_count,
                                                                   byte[]data,
                                                                   ref uint
                                                                   done_count);

    /**ReadData2**********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ReadData2")] public static extern short ReadData2(byte
                                                                     file_id,
                                                                     uint
                                                                     from_offset,
                                                                     uint
                                                                     max_count,
                                                                     byte
                                                                     []data,
                                                                     ref uint
                                                                     done_count);

    /**WriteData**********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_WriteData")] public static extern short WriteData(byte
                                                                     file_id,
                                                                     byte
                                                                     comm_mode,
                                                                     uint
                                                                     from_offset,
                                                                     uint
                                                                     size,
                                                                     byte
                                                                     []data);

    /**WriteData2*********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_WriteData2")] public static extern short WriteData2(byte
                                                                       file_id,
                                                                       uint
                                                                       from_offset,
                                                                       uint
                                                                       size,
                                                                       byte
                                                                       []data);

    /**GetValue***********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetValue")] public static extern short GetValue(byte
                                                                   file_id,
                                                                   byte
                                                                   comm_mode,
                                                                   ref int
                                                                   value);

    /**GetValue2**********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_GetValue2")] public static extern short GetValue2(byte
                                                                     file_id,
                                                                     ref int
                                                                     value);

    /**ReadRecords********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ReadRecords")] public static extern short ReadRecords(byte
                                                                         file_id,
                                                                         byte
                                                                         comm_mode,
                                                                         uint
                                                                         from_record,
                                                                         uint
                                                                         max_record_count,
                                                                         uint
                                                                         record_size,
                                                                         byte
                                                                         []data,
                                                                         ref
                                                                         uint
                                                                         record_count);

    /**ReadRecords2*******************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ReadRecords2")] public static extern short
ReadRecords2(byte file_id, uint from_record, uint max_record_count,
          uint record_size, byte[]data, ref uint record_count);

    /**WriteRecord********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_WriteRecord")] public static extern short WriteRecord(byte
                                                                         file_id,
                                                                         byte
                                                                         comm_mode,
                                                                         uint
                                                                         from_offset,
                                                                         uint
                                                                         size,
                                                                         byte
                                                                         []data);

    /**WriteRecord2*******************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_WriteRecord2")] public static extern short WriteRecord2(byte
                                                                           file_id,
                                                                           uint
                                                                           from_offset,
                                                                           uint
                                                                           size,
                                                                           byte
                                                                           [] data);

    /**ClearRecordFile****************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_ClearRecordFile")] public static extern short ClearRecordFile(byte file_id);

#endregion

#region Credit/Debit
    /**LimitedCredit******************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_LimitedCredit")] public static extern short
LimitedCredit(byte file_id, byte comm_mode, int amount);

    /**LimitedCredit2*****************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_LimitedCredit2")] public static extern short
LimitedCredit2(byte file_id, int amount);

    /**Credit*************************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_Credit")] public static extern short Credit(byte file_id,
                                                               byte comm_mode,
                                                               int amount);

    /**Credit2************************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_Credit2")] public static extern short Credit2(byte file_id,
                                                                 int amount);

    /**Debit**************************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_Debit")] public static extern short Debit(byte file_id,
                                                             byte comm_mode,
                                                             int amount);

    /**Debit2*************************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_Debit2")] public static extern short Debit2(byte file_id,
                                                               int amount);
#endregion

#region Transaction
    /**CommitTransaction**************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_CommitTransaction")] public static extern short
CommitTransaction();

    /**AbortTransaction***************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFireCard_AbortTransaction")] public static extern short
AbortTransaction();

#endregion

#region DES / 3-DES
    /**DES_SetKey*********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "SPROX_Desfire_DES_SetKey")] public static extern short DES_SetKey(byte
                                                                   [] key);

    /**DES_Encrypt********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "SPROX_Desfire_DES_Encrypt")] public static extern short DES_Encrypt(byte
                                                                     [] inoutbuf);

    /**DES_Decrypt********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "SPROX_Desfire_DES_Decrypt")] public static extern short DES_Decrypt(byte
                                                                     [] inoutbuf);

    /**TDES_SetKey********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "SPROX_Desfire_TDES_SetKey")] public static extern short TDES_SetKey(byte
                                                                     [] key1, 
                                                                     byte
                                                                     [] key2,
                                                                     byte
                                                                     [] key3);

    /**TDES_Encrypt********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "SPROX_Desfire_TDES_Encrypt")] public static extern short TDES_Encrypt(byte
                                                                       [] inoutbuf);

    /**TDES_Decrypt********************/
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "SPROX_Desfire_TDES_Decrypt")] public static extern short TDES_Decrypt(byte
                                                                       [] inoutbuf);

#endregion

#region GetErrorMessage
    /**GetErrorMessage****************/
#if UNICODE
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFire_GetErrorMessage")] private static extern unsafe char
*GetErrorMessageW(short status);

    public static unsafe string GetErrorMessage(short rc)
    {
      char *msg = GetErrorMessageW(rc);

      return new string(msg);
    }
#else
    [DllImport
     ("sprox_desfire.dll", CharSet = CharSet.Auto, EntryPoint =
      "DesFire_GetErrorMessage")] private static extern unsafe byte
* GetErrorMessageA(short status);

    public static unsafe string GetErrorMessage(short rc)
    {
      byte *msg = GetErrorMessageA(rc);

      return new string((sbyte *) msg);
    }
#endif

#endregion
  }
}
